from flask import request
from flask_restful import fields, reqparse, Resource, marshal, marshal_with, abort

from main.apis.utils import login_required, permission_required
from main.models.admin.admin_model import PERMISSION_SU, PERMISSION_W
from main.models.goods.goods_model import Goods

goods_fields = {  # 声明各字段数据类型用来序列化
    'id': fields.Integer,
    'name': fields.String(attribute='g_name'),
    'price': fields.Float(attribute='g_price'),
    'count': fields.Integer(attribute='g_count'),
    'url': fields.Url('goodobj', absolute=True)  # 生成url需要写单个good类
}

single_good_fields = {  # 单个商品的序列化格式
    'data': fields.Nested(goods_fields),  # 将goods数据级联到data上
    'status': fields.Integer,
    'msg': fields.String
}

all_goods_fields = {  # 全部商品的序列化格式
    'status': fields.Integer,
    'msg': fields.String,
    'data': fields.List(fields.Nested(goods_fields)),  # 将级联的goods数据放到一个列表里
    'desc': fields.String(default='暂无')
}

parser = reqparse.RequestParser()  # 获取浏览器传递的请求参数
# parser.add_argument('action', type=str, required=True, help='请输入请求参数')
parser.add_argument('g_name', type=str, required=True, help='请输入商品名称(g_name)')
parser.add_argument('g_price', type=float, required=True, help='请输入价格(g_price)')
parser.add_argument('g_count', type=float, required=True, help='请输入商品数量(g_count)')
parser.add_argument('mu', action='append')
parser.add_argument('name', dest='public_name')
parser.add_argument('fldt', action='append', location=['cookies', 'args'])
parser.add_argument('User-Agent', dest='ua', location='headers')


class GoodsList(Resource):
    """
    对商品的写操作需要登录和权限，login_required，删除和增加操作需要有特殊权限(permission_required)
    """
    @login_required
    def get(self):
        goods_list = Goods.query.all()

        data = {
            'status': 200,
            'msg': '获取成功',
            'data': goods_list
        }
        return marshal(data, all_goods_fields)  # 序列化方式之一，marshal(数据, 序列化后的数据格式)
        # return data

    @permission_required(PERMISSION_SU)
    @marshal_with(single_good_fields)  # 序列化方式之二，装饰器marshal_with(序列化后的序据格式)
    def post(self):
        args = parser.parse_args()
        print(args)
        g_name = args.get('g_name')
        g_price = args.get('g_price')
        g_count = args.get('g_count')
        good = Goods()
        good.g_name = g_name
        good.g_price = g_price
        good.g_count = g_count
        if not good.save():
            abort(400)
        data = {
            'msg': '商品添加成功',
            'status': 201,
            'data': good
        }

        return data


class GoodObj(Resource):
    # @marshal_with(single_good_fields)  # 序列化方式之二，装饰器marshal_with(序列化后的序据格式)
    def get(self, id):
        good = Goods.query.get(id)
        if not good:
            abort(404, error='无此商品！')
        data = {
            'status': 200,
            'msg': 'ok',
            'data': good
        }
        result = marshal(data, single_good_fields, envelope=good.id)  # envelope为可选关键参数，值为序列化后的data
        print(result)

        return result

    @permission_required(PERMISSION_SU)
    def delete(self, id):
        good = Goods.query.get(id)
        if not good:
            abort(404, error=f'此 id --> {id} 对应的商品不存在！')
        if not good.delete():
            abort(400, error='删除失败')
        data = {
            'status': 404,
            'msg': '删除成功'
        }

        return data

    @permission_required(PERMISSION_W)
    def put(self, id):
        good = Goods.query.get(id)
        if not good:
            abort(404)
        g_price = request.form.get('g_price')
        g_name = request.form.get('g_name')
        good.g_price = g_price
        good.g_name = g_name
        if not good.save():
            abort(400)
        data = {
            'msg': '修改成功',
            'status': 201,
            'data': good
        }

        return marshal(data, single_good_fields)

    @permission_required(PERMISSION_W)
    @marshal_with(single_good_fields)
    def patch(self, id):
        good = Goods.query.get(id)
        if not good:
            abort(404)
        g_price = request.form.get('g_price')
        g_name = request.form.get('g_name')
        good.g_price = g_price or good.g_price
        good.g_name = g_name or good.g_name
        if not good.save():
            abort(400)
        data = {
            'msg': '修改成功',
            'status': 201,
            'data': good
        }

        return data
